package com.example.demo.api.sql;

import cn.hutool.json.JSONUtil;
import com.example.demo.api.constant.ColumnDataType;
import com.example.demo.api.constant.FilterValueType;
import com.example.demo.api.entity.FieldEntity;
import com.example.demo.api.entity.FilterEntity;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.Parenthesis;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.Select;

import java.io.StringReader;

@Slf4j
public class FilterExpressionHandler {

    public static Expression handlerEQ(FilterEntity filterEntity) {
        FieldEntity field = filterEntity.getField();
        String colDataType = field.getColDataType();
        Column column = CommonQueryService.getColumn(field);
        String value = filterEntity.getValue();
        String valueType = filterEntity.getValueType();
        EqualsTo equalsTo = new EqualsTo().withLeftExpression(column);
        switch (valueType) {
            case FilterValueType.CONSTANT:
                if (ColumnDataType.STRING.equals(colDataType)) {
                    equalsTo.withRightExpression(new StringValue(value));
                } else if (ColumnDataType.NUMBER.equals(colDataType)) {
                    equalsTo.withRightExpression(new StringValue(value));
                } else {
                    log.error("不支持的ColumnDataType: {}", colDataType);
                    throw new IllegalArgumentException("不支持的ColumnDataType: " + colDataType);
                }
                break;
            case FilterValueType.VARIABLE:
                // TODO 支持变量方式
                break;
            case FilterValueType.FIELD:
                FieldEntity rightColumn = JSONUtil.toBean(value, FieldEntity.class);
                equalsTo.withRightExpression(CommonQueryService.getColumn(rightColumn));
                break;
            case FilterValueType.SQL:
                CCJSqlParserManager parserManager = new CCJSqlParserManager();
                try {
                    Select select = (Select) parserManager.parse(new StringReader(value));
                    equalsTo.withRightExpression(new Parenthesis(select));
                } catch (JSQLParserException e) {
                    log.error("{} 不是合法的SQL语句，解析失败！", value);
                    throw new IllegalArgumentException(value + " 不是合法的SQL语句");
                }
                break;
            default:
                log.error("不支持的FilterValueType: {}", valueType);
                throw new IllegalArgumentException("不支持的FilterValueType: " + valueType);
        }
        return equalsTo;
    }

    public static Expression handlerNE(FilterEntity filterEntity) {
        FieldEntity field = filterEntity.getField();
        String colDataType = field.getColDataType();
        Column column = CommonQueryService.getColumn(field);
        String value = filterEntity.getValue();
        String valueType = filterEntity.getValueType();
        NotEqualsTo equalsTo = new NotEqualsTo().withLeftExpression(column);
        switch (valueType) {
            case FilterValueType.CONSTANT:
                if (ColumnDataType.STRING.equals(colDataType)) {
                    equalsTo.withRightExpression(new StringValue(value));
                } else if (ColumnDataType.NUMBER.equals(colDataType)) {
                    equalsTo.withRightExpression(new StringValue(value));
                } else {
                    log.error("不支持的ColumnDataType: {}", colDataType);
                    throw new IllegalArgumentException("不支持的ColumnDataType: " + colDataType);
                }
                break;
            case FilterValueType.VARIABLE:
                // TODO 支持变量方式
                break;
            case FilterValueType.FIELD:
                FieldEntity rightColumn = JSONUtil.toBean(value, FieldEntity.class);
                equalsTo.withRightExpression(CommonQueryService.getColumn(rightColumn));
                break;
            case FilterValueType.SQL:
                CCJSqlParserManager parserManager = new CCJSqlParserManager();
                try {
                    Select select = (Select) parserManager.parse(new StringReader(value));
                    equalsTo.withRightExpression(new Parenthesis(select));
                } catch (JSQLParserException e) {
                    log.error("{} 不是合法的SQL语句，解析失败！", value);
                    throw new IllegalArgumentException(value + " 不是合法的SQL语句");
                }
                break;
            default:
                log.error("不支持的FilterValueType: {}", valueType);
                throw new IllegalArgumentException("不支持的FilterValueType: " + valueType);
        }
        return equalsTo;
    }

    public static Expression handlerGT(FilterEntity filterEntity) {
        FieldEntity field = filterEntity.getField();
        String colDataType = field.getColDataType();
        Column column = CommonQueryService.getColumn(field);
        String value = filterEntity.getValue();
        String valueType = filterEntity.getValueType();
        GreaterThan greaterThan = new GreaterThan().withLeftExpression(column);
        switch (valueType) {
            case FilterValueType.CONSTANT:
                if (ColumnDataType.STRING.equals(colDataType)) {
                    greaterThan.withRightExpression(new StringValue(value));
                } else if (ColumnDataType.NUMBER.equals(colDataType)) {
                    greaterThan.withRightExpression(new StringValue(value));
                } else {
                    log.error("不支持的ColumnDataType: {}", colDataType);
                    throw new IllegalArgumentException("不支持的ColumnDataType: " + colDataType);
                }
                break;
            case FilterValueType.VARIABLE:
                // TODO 支持变量方式
                break;
            case FilterValueType.FIELD:
                FieldEntity rightColumn = JSONUtil.toBean(value, FieldEntity.class);
                greaterThan.withRightExpression(CommonQueryService.getColumn(rightColumn));
                break;
            case FilterValueType.SQL:
                CCJSqlParserManager parserManager = new CCJSqlParserManager();
                try {
                    Select select = (Select) parserManager.parse(new StringReader(value));
                    greaterThan.withRightExpression(new Parenthesis(select));
                } catch (JSQLParserException e) {
                    log.error("{} 不是合法的SQL语句，解析失败！", value);
                    throw new IllegalArgumentException(value + " 不是合法的SQL语句");
                }
                break;
            default:
                log.error("不支持的FilterValueType: {}", valueType);
                throw new IllegalArgumentException("不支持的FilterValueType: " + valueType);
        }
        return greaterThan;
    }

    public static Expression handlerLT(FilterEntity filterEntity) {
        FieldEntity field = filterEntity.getField();
        String colDataType = field.getColDataType();
        Column column = CommonQueryService.getColumn(field);
        String value = filterEntity.getValue();
        String valueType = filterEntity.getValueType();
        MinorThan minorThan = new MinorThan().withLeftExpression(column);
        switch (valueType) {
            case FilterValueType.CONSTANT:
                if (ColumnDataType.STRING.equals(colDataType)) {
                    minorThan.withRightExpression(new StringValue(value));
                } else if (ColumnDataType.NUMBER.equals(colDataType)) {
                    minorThan.withRightExpression(new StringValue(value));
                } else {
                    log.error("不支持的ColumnDataType: {}", colDataType);
                    throw new IllegalArgumentException("不支持的ColumnDataType: " + colDataType);
                }
                break;
            case FilterValueType.VARIABLE:
                // TODO 支持变量方式
                break;
            case FilterValueType.FIELD:
                FieldEntity rightColumn = JSONUtil.toBean(value, FieldEntity.class);
                minorThan.withRightExpression(CommonQueryService.getColumn(rightColumn));
                break;
            case FilterValueType.SQL:
                CCJSqlParserManager parserManager = new CCJSqlParserManager();
                try {
                    Select select = (Select) parserManager.parse(new StringReader(value));
                    minorThan.withRightExpression(new Parenthesis(select));
                } catch (JSQLParserException e) {
                    log.error("{} 不是合法的SQL语句，解析失败！", value);
                    throw new IllegalArgumentException(value + " 不是合法的SQL语句");
                }
                break;
            default:
                log.error("不支持的FilterValueType: {}", valueType);
                throw new IllegalArgumentException("不支持的FilterValueType: " + valueType);
        }
        return minorThan;
    }

    public static Expression handlerGE(FilterEntity filterEntity) {
        FieldEntity field = filterEntity.getField();
        String colDataType = field.getColDataType();
        Column column = CommonQueryService.getColumn(field);
        String value = filterEntity.getValue();
        String valueType = filterEntity.getValueType();
        GreaterThanEquals greaterThanEquals = new GreaterThanEquals().withLeftExpression(column);
        switch (valueType) {
            case FilterValueType.CONSTANT:
                if (ColumnDataType.STRING.equals(colDataType)) {
                    greaterThanEquals.withRightExpression(new StringValue(value));
                } else if (ColumnDataType.NUMBER.equals(colDataType)) {
                    greaterThanEquals.withRightExpression(new StringValue(value));
                } else {
                    log.error("不支持的ColumnDataType: {}", colDataType);
                    throw new IllegalArgumentException("不支持的ColumnDataType: " + colDataType);
                }
                break;
            case FilterValueType.VARIABLE:
                // TODO 支持变量方式
                break;
            case FilterValueType.FIELD:
                FieldEntity rightColumn = JSONUtil.toBean(value, FieldEntity.class);
                greaterThanEquals.withRightExpression(CommonQueryService.getColumn(rightColumn));
                break;
            case FilterValueType.SQL:
                CCJSqlParserManager parserManager = new CCJSqlParserManager();
                try {
                    Select select = (Select) parserManager.parse(new StringReader(value));
                    greaterThanEquals.withRightExpression(new Parenthesis(select));
                } catch (JSQLParserException e) {
                    log.error("{} 不是合法的SQL语句，解析失败！", value);
                    throw new IllegalArgumentException(value + " 不是合法的SQL语句");
                }
                break;
            default:
                log.error("不支持的FilterValueType: {}", valueType);
                throw new IllegalArgumentException("不支持的FilterValueType: " + valueType);
        }
        return greaterThanEquals;
    }

    public static Expression handlerLE(FilterEntity filterEntity) {
        FieldEntity field = filterEntity.getField();
        String colDataType = field.getColDataType();
        Column column = CommonQueryService.getColumn(field);
        String value = filterEntity.getValue();
        String valueType = filterEntity.getValueType();
        MinorThanEquals minorThanEquals = new MinorThanEquals().withLeftExpression(column);
        switch (valueType) {
            case FilterValueType.CONSTANT:
                if (ColumnDataType.STRING.equals(colDataType)) {
                    minorThanEquals.withRightExpression(new StringValue(value));
                } else if (ColumnDataType.NUMBER.equals(colDataType)) {
                    minorThanEquals.withRightExpression(new StringValue(value));
                } else {
                    log.error("不支持的ColumnDataType: {}", colDataType);
                    throw new IllegalArgumentException("不支持的ColumnDataType: " + colDataType);
                }
                break;
            case FilterValueType.VARIABLE:
                // TODO 支持变量方式
                break;
            case FilterValueType.FIELD:
                FieldEntity rightColumn = JSONUtil.toBean(value, FieldEntity.class);
                minorThanEquals.withRightExpression(CommonQueryService.getColumn(rightColumn));
                break;
            case FilterValueType.SQL:
                CCJSqlParserManager parserManager = new CCJSqlParserManager();
                try {
                    Select select = (Select) parserManager.parse(new StringReader(value));
                    minorThanEquals.withRightExpression(new Parenthesis(select));
                } catch (JSQLParserException e) {
                    log.error("{} 不是合法的SQL语句，解析失败！", value);
                    throw new IllegalArgumentException(value + " 不是合法的SQL语句");
                }
                break;
            default:
                log.error("不支持的FilterValueType: {}", valueType);
                throw new IllegalArgumentException("不支持的FilterValueType: " + valueType);
        }
        return minorThanEquals;
    }

    public static Expression handlerLIKE(FilterEntity filterEntity) {
        FieldEntity field = filterEntity.getField();
        String colDataType = field.getColDataType();
        Column column = CommonQueryService.getColumn(field);
        String value = filterEntity.getValue();
        String valueType = filterEntity.getValueType();
        LikeExpression likeExpression = new LikeExpression().withLeftExpression(column);
        switch (valueType) {
            case FilterValueType.CONSTANT:
                if (ColumnDataType.STRING.equals(colDataType)) {
                    likeExpression.withRightExpression(new StringValue(value));
                } else if (ColumnDataType.NUMBER.equals(colDataType)) {
                    likeExpression.withRightExpression(new StringValue(value));
                } else {
                    log.error("不支持的ColumnDataType: {}", colDataType);
                    throw new IllegalArgumentException("不支持的ColumnDataType: " + colDataType);
                }
                break;
            case FilterValueType.VARIABLE:
                // TODO 支持变量方式
                break;
            case FilterValueType.FIELD:
                FieldEntity rightColumn = JSONUtil.toBean(value, FieldEntity.class);
                likeExpression.withRightExpression(CommonQueryService.getColumn(rightColumn));
                break;
            case FilterValueType.SQL:
                CCJSqlParserManager parserManager = new CCJSqlParserManager();
                try {
                    Select select = (Select) parserManager.parse(new StringReader(value));
                    likeExpression.withRightExpression(new Parenthesis(select));
                } catch (JSQLParserException e) {
                    log.error("{} 不是合法的SQL语句，解析失败！", value);
                    throw new IllegalArgumentException(value + " 不是合法的SQL语句");
                }
                break;
            default:
                log.error("不支持的FilterValueType: {}", valueType);
                throw new IllegalArgumentException("不支持的FilterValueType: " + valueType);
        }
        return likeExpression;
    }

    public static Expression handlerBETWEEN(FilterEntity filterEntity) {
        // TODO
        return null;
    }

    public static Expression handlerIN(FilterEntity filterEntity) {
        FieldEntity field = filterEntity.getField();
        String colDataType = field.getColDataType();
        Column column = CommonQueryService.getColumn(field);
        String value = filterEntity.getValue();
        String valueType = filterEntity.getValueType();
        InExpression inExpression = new InExpression().withLeftExpression(column);
        switch (valueType) {
            case FilterValueType.CONSTANT:
                if (ColumnDataType.STRING.equals(colDataType)) {
                    inExpression.withRightExpression(new StringValue(value));
                } else if (ColumnDataType.NUMBER.equals(colDataType)) {
                    inExpression.withRightExpression(new StringValue(value));
                } else {
                    log.error("不支持的ColumnDataType: {}", colDataType);
                    throw new IllegalArgumentException("不支持的ColumnDataType: " + colDataType);
                }
                break;
            case FilterValueType.VARIABLE:
                // TODO 支持变量方式
                break;
            case FilterValueType.FIELD:
                FieldEntity rightColumn = JSONUtil.toBean(value, FieldEntity.class);
                inExpression.withRightExpression(CommonQueryService.getColumn(rightColumn));
                break;
            case FilterValueType.SQL:
                CCJSqlParserManager parserManager = new CCJSqlParserManager();
                try {
                    Select select = (Select) parserManager.parse(new StringReader(value));
                    inExpression.withRightExpression(new Parenthesis(select));
                } catch (JSQLParserException e) {
                    log.error("{} 不是合法的SQL语句，解析失败！", value);
                    throw new IllegalArgumentException(value + " 不是合法的SQL语句");
                }
                break;
            default:
                log.error("不支持的FilterValueType: {}", valueType);
                throw new IllegalArgumentException("不支持的FilterValueType: " + valueType);
        }
        return inExpression;
    }

    public static Expression handlerISNULL(FilterEntity filterEntity) {
        FieldEntity field = filterEntity.getField();
        String colDataType = field.getColDataType();
        Column column = CommonQueryService.getColumn(field);
        String operator = filterEntity.getOperator();
        String value = filterEntity.getValue();
        String valueType = filterEntity.getValueType();
        return new IsNullExpression().withLeftExpression(column);
    }

}
